﻿#region Copyright(C) 2018 FI Ltd. All rights reserved.
// ==================================================================================================
// Copyright(C) 2018 FI Ltd. All rights reserved.
//
// SYSTEM NAME	    : FI.Net Application Framework
// COMPONENT ID	    : FI.Core
// COMPONENT DESC   : FI.Net Core Foundation
//
// CREATED DATE/BY  : 18 Aug 2018 / Tian Mi
//
// REVISION HISTORY :	
// DATE/BY			SR#/CS/PM#/OTHERS		DESCRIPTION OF CHANGE
// ==================================================================================================
#endregion

using FI.Core.Properties;
using FI.Core.Utilities;
using System;
using System.ComponentModel;
using System.Configuration;
using System.Globalization;

namespace FI.Core.Configuration
{
    /// <summary>
    /// A <see cref="ConfigurationConverterBase"/> for type conversion between <see cref="Type"/> and <see cref="string"/>.
    /// </summary>
    public class AssemblyQualifiedTypeNameConfigurationConverter: ConfigurationConverterBase
    {
        /// <summary>
        /// Converts the given object to the type of this converter, using the specified context and culture information.
        /// </summary>
        /// <param name="context">An <see cref="T:System.ComponentModel.ITypeDescriptorContext" /> that provides a format context.</param>
        /// <param name="culture">The <see cref="T:System.Globalization.CultureInfo" /> to use as the current culture.</param>
        /// <param name="value">The <see cref="T:System.Object" /> to convert.</param>
        /// <returns>
        /// An <see cref="T:System.Object" /> that represents the converted value.
        /// </returns>
        /// <exception cref="System.ArgumentException"></exception>
        public override object ConvertFrom(ITypeDescriptorContext context, CultureInfo culture, object value)
        {
            string typeName = value as string;
            if (string.IsNullOrWhiteSpace(typeName))
            {
                return null;
            }
            Type type = Type.GetType(typeName);
            if (null == type)
            { 
                throw new ArgumentException(Resources.ExceptionCannotResolveTypeName.Format(value));
            }
            return type;
        }

        /// <summary>
        /// Converts the given value object to the specified type, using the specified context and culture information.
        /// </summary>
        /// <param name="context">An <see cref="T:System.ComponentModel.ITypeDescriptorContext" /> that provides a format context.</param>
        /// <param name="culture">A <see cref="T:System.Globalization.CultureInfo" />. If null is passed, the current culture is assumed.</param>
        /// <param name="value">The <see cref="T:System.Object" /> to convert.</param>
        /// <param name="destinationType">The <see cref="T:System.Type" /> to convert the <paramref name="value" /> parameter to.</param>
        /// <returns>
        /// An <see cref="T:System.Object" /> that represents the converted value.
        /// </returns>
        public override object ConvertTo(ITypeDescriptorContext context, CultureInfo culture, object value, Type destinationType)
        {
            Type type = value as Type;
            if (null == type)
            {
                return null;
            }
            return type.AssemblyQualifiedName;
        }
    }
}
